package com.wgke.bluetooth.view;


import android.opengl.GLES20;
import android.opengl.GLSurfaceView;
import android.opengl.Matrix;

import com.google.gson.Gson;
import com.wgke.bluetooth.utils.LogUtil;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.util.Random;

import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;

public class PressureRenderer implements GLSurfaceView.Renderer {
    private static final int WIDTH = 150;
    private static final int HEIGHT = 100;
    private static final float CONTENT_ASPECT = (float) WIDTH / HEIGHT;

    // 矩阵
    private final float[] mProjectionMatrix = new float[16];
    private final float[] mViewMatrix = new float[16];
    private final float[] mModelMatrix = new float[16];
    private final float[] mMVPMatrix = new float[16];

    // 3D效果参数
    public float m3DEffectStrength = 1.0f; // 0.1-1.0之间
    public float mTarget3DEffectStrength = 1.0f;
    private float mTransitionProgress = 1.0f;
    private float mBaseScale = 1.5f;// 增大基础缩放因子1.0
    private static final float SIZE_COMPENSATION = 1.5f; // 尺寸补偿因子 1.25

    // 3D参数基准值
    private static final float MAX_TILT_ANGLE = 30.0f;
    public float MAX_HEIGHT_SCALE = 0.6f;// 增大高度比例
    public float CAMERA_Z = 2.5f;// 减小相机距离使图形看起来更大 3.0
    public float FOV_3D = 50.0f;// 增大视野角度 45
    public float NEAR_PLANE = 0.5f;// 调整近平面 1.0
    public float FAR_PLANE = 20.0f;

    // 数据
    private float[] mPressureData = new float[WIDTH * HEIGHT];
    private FloatBuffer mVertexBuffer;
    private FloatBuffer mColorBuffer;

    // 渲染参数
    private int mProgram;
    public float mPointSize = 5.0f;//4.0增加到6.0
    private float mAspectRatio = 1.0f;



    @Override
    public void onSurfaceCreated(GL10 gl, EGLConfig config) {
        GLES20.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
        GLES20.glEnable(GLES20.GL_DEPTH_TEST);
        initShaders();
        initTestData();
    }

    @Override
    public void onSurfaceChanged(GL10 gl, int width, int height) {
        GLES20.glViewport(0, 0, width, height);
        mAspectRatio = (float) width / height;

        Matrix.setLookAtM(mViewMatrix, 0,
                0, 0, CAMERA_Z,
                0f, 0f, 0f,
                0f, 1.0f, 0.0f);

        updateProjectionMatrix();
        updateModelMatrix();
    }

    private void updateProjectionMatrix() {
        // 计算3D模式下实际显示的宽度
        float visible3DWidth = 2 * CAMERA_Z * (float) Math.tan(Math.toRadians(FOV_3D / 2));

        // 根据3D效果强度计算补偿缩放
        mBaseScale = 1.0f + (SIZE_COMPENSATION - 1.0f) * m3DEffectStrength;

        // 始终使用透视投影（纯3D模式）
        Matrix.perspectiveM(mProjectionMatrix, 0, FOV_3D, mAspectRatio, NEAR_PLANE, FAR_PLANE);
        Matrix.scaleM(mProjectionMatrix, 0, mBaseScale, mBaseScale, 1.0f);
    }

    private void updateModelMatrix() {
        Matrix.setIdentityM(mModelMatrix, 0);
        // 根据当前3D效果强度应用倾斜
        float currentTilt = MAX_TILT_ANGLE * m3DEffectStrength;
        Matrix.rotateM(mModelMatrix, 0, -currentTilt, 1.0f, 0.0f, 0.0f);
    }

    @Override
    public void onDrawFrame(GL10 gl) {
        GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT);

        // 过渡动画
        if (mTransitionProgress < 1.0f) {
            mTransitionProgress += 0.05f;
            if (mTransitionProgress > 1.0f) {
                mTransitionProgress = 1.0f;
                m3DEffectStrength = mTarget3DEffectStrength;
            } else {
                // 平滑过渡
                m3DEffectStrength = m3DEffectStrength +
                        (mTarget3DEffectStrength - m3DEffectStrength) * 0.1f;
            }
            updateProjectionMatrix();
            updateModelMatrix();
        }

        // 计算MVP矩阵
        Matrix.multiplyMM(mMVPMatrix, 0, mViewMatrix, 0, mModelMatrix, 0);
        Matrix.multiplyMM(mMVPMatrix, 0, mProjectionMatrix, 0, mMVPMatrix, 0);

        drawPressureMatrix();
    }

    private void initShaders() {
        String vertexShaderCode =
                "uniform mat4 uMVPMatrix;" +
                        "attribute vec4 vPosition;" +
                        "attribute vec4 vColor;" +
                        "varying vec4 fColor;" +
                        "uniform float uPointSize;" +
                        "void main() {" +
                        "  gl_Position = uMVPMatrix * vPosition;" +
                        "  fColor = vColor;" +
                        "  gl_PointSize = uPointSize;" +
                        "}";

        String fragmentShaderCode =
                "precision mediump float;" +
                        "varying vec4 fColor;" +
                        "void main() {" +
                        "  gl_FragColor = fColor;" +
                        "}";

        int vertexShader = loadShader(GLES20.GL_VERTEX_SHADER, vertexShaderCode);
        int fragmentShader = loadShader(GLES20.GL_FRAGMENT_SHADER, fragmentShaderCode);

        mProgram = GLES20.glCreateProgram();
        GLES20.glAttachShader(mProgram, vertexShader);
        GLES20.glAttachShader(mProgram, fragmentShader);
        GLES20.glLinkProgram(mProgram);
    }

    private int loadShader(int type, String shaderCode) {
        int shader = GLES20.glCreateShader(type);
        GLES20.glShaderSource(shader, shaderCode);
        GLES20.glCompileShader(shader);
        return shader;
    }

    private void initTestData() {
        // 初始化测试数据（中心高压区域）
        Random random = new Random();

        // 首先生成全部分辨率的原始数据
        float[] tempData = new float[WIDTH * HEIGHT];
        for (int x = 0; x < WIDTH; x++) {
            for (int y = 0; y < HEIGHT; y++) {
                float distX = (x - WIDTH / 2) / (float) (WIDTH / 2);
                float distY = (y - HEIGHT / 2) / (float) (HEIGHT / 2);
                float dist = (float) Math.sqrt(distX * distX + distY * distY);

                if (dist < 0.8f) {
                    float baseValue = 0.7f + random.nextFloat() * 0.3f;
                    float attenuation = (float) Math.pow(1 - dist / 0.8f, 2);
                    tempData[y * WIDTH + x] = baseValue * attenuation;
                    tempData[y * WIDTH + x] += (random.nextFloat() - 0.5f) * 0.1f;
                    tempData[y * WIDTH + x] = Math.max(0.1f, Math.min(1.0f, tempData[y * WIDTH + x]));
                } else {
                    tempData[y * WIDTH + x] = 0.1f;
                }
            }
        }

        // 对X方向每两个相邻点取平均
        for (int y = 0; y < HEIGHT; y++) {
            for (int x = 0; x < WIDTH; x += 2) {
                if (x + 1 < WIDTH) {  // 确保不越界
                    float avg = (tempData[y * WIDTH + x] + tempData[y * WIDTH + x + 1]) / 2.0f;
                    mPressureData[y * WIDTH + x] = avg;
                    mPressureData[y * WIDTH + x + 1] = avg;
                } else {
                    // 如果宽度是奇数，最后一个点保持不变
                    mPressureData[y * WIDTH + x] = tempData[y * WIDTH + x];
                }
            }
        }

        LogUtil.d("PressureRenderer", new Gson().toJson(mPressureData));
    }

    public void initTestData(int centerX, int centerY) {
        // 初始化测试数据（单点压力中心，平滑衰减）
        // 首先生成全部分辨率的原始数据

        float[] tempData = new float[WIDTH * HEIGHT];
        float maxRadius = 30.0f;  // 50像素处衰减到0

        for (int x = 0; x < WIDTH; x++) {
            for (int y = 0; y < HEIGHT; y++) {
                // 计算当前点到中心点的距离
                float distX = x - centerX;
                float distY = y - centerY;
                float dist = (float) Math.sqrt(distX * distX + distY * distY);

                if (dist <= maxRadius) {
                    // 使用正弦函数，使中心点(0)压力最大(1.0)，在maxRadius处衰减到0
                    float normalizedDist = (dist / maxRadius) * (float) (Math.PI / 2);
                    float attenuation = (float) Math.cos(normalizedDist);  // cos在[0,π/2]从1降到0
                    tempData[y * WIDTH + x] = attenuation;
                } else {
                    // 半径以外的区域压力为0
                    tempData[y * WIDTH + x] = 0.0f;
                }
            }
        }

        // 对X方向每两个相邻点取平均
        for (int y = 0; y < HEIGHT; y++) {
            for (int x = 0; x < WIDTH; x += 2) {
                if (x + 1 < WIDTH) {  // 确保不越界
                    float avg = (tempData[y * WIDTH + x] + tempData[y * WIDTH + x + 1]) / 2.0f;
                    mPressureData[y * WIDTH + x] = avg;
                    mPressureData[y * WIDTH + x + 1] = avg;
                } else {
                    // 如果宽度是奇数，最后一个点保持不变
                    mPressureData[y * WIDTH + x] = tempData[y * WIDTH + x];
                }
            }
        }
    }
    private void drawPressureMatrix() {
        float[] vertices = new float[WIDTH * HEIGHT * 3];
        float[] colors = new float[WIDTH * HEIGHT * 4];

        // 计算3D模式下实际显示的宽度（用于统一缩放）
        float visible3DWidth = 2 * CAMERA_Z * (float) Math.tan(Math.toRadians(FOV_3D / 2));
        float xScale = visible3DWidth / WIDTH;
        float yScale = xScale / CONTENT_ASPECT;

        // 颜色阈值和对应的颜色值
        float[] thresholds = new float[]{0f, 0.14f, 0.35f, 0.60f, 0.75f, 0.95f};
        float[][] thresholdColors = {
                {0.5f, 0.5f, 0.5f, 1.0f},    // 灰色
                {0.0f, 0.0f, 1.0f, 1.0f},     // 蓝色
                {0.0f, 1.0f, 0.0f, 1.0f},     // 绿色
                {1.0f, 1.0f, 0.0f, 1.0f},     // 黄色
                {1.0f, 0.5f, 0.0f, 1.0f},     // 橘色
                {1.0f, 0.0f, 0.0f, 1.0f}      // 红色
        };

        for (int x = 0; x < WIDTH; x++) {
            for (int y = 0; y < HEIGHT; y++) {
                int index = y * WIDTH + x;
                float pressure = mPressureData[index];

                // 基础坐标计算（应用补偿缩放）
                float baseX = (x - WIDTH / 2) * xScale / mBaseScale;
                float baseY = (y - HEIGHT / 2) * yScale / mBaseScale;

                // 3D效果坐标计算
                vertices[index * 3] = baseX;
                vertices[index * 3 + 1] = baseY * (float) Math.cos(Math.toRadians(MAX_TILT_ANGLE * m3DEffectStrength));
                vertices[index * 3 + 2] = (pressure - 0.1f) * MAX_HEIGHT_SCALE * m3DEffectStrength;

                // 颜色计算（基于0.1-1.0范围）
                float normalizedPressure = (pressure - 0.1f) / 0.9f;
                normalizedPressure = Math.max(0.0f, Math.min(1.0f, normalizedPressure)); // 确保在0-1范围内

                // 根据阈值确定颜色
                if (normalizedPressure <= thresholds[0]) {
                    System.arraycopy(thresholdColors[0], 0, colors, index * 4, 4);
                } else if (normalizedPressure >= thresholds[thresholds.length - 1]) {
                    System.arraycopy(thresholdColors[thresholdColors.length - 1], 0, colors, index * 4, 4);
                } else {
                    // 找到当前压力值所在的区间
                    int i = 0;
                    for (; i < thresholds.length - 1; i++) {
                        if (normalizedPressure >= thresholds[i] && normalizedPressure < thresholds[i + 1]) {
                            break;
                        }
                    }

                    // 计算插值比例
                    float t = (normalizedPressure - thresholds[i]) / (thresholds[i + 1] - thresholds[i]);

                    // 插值计算颜色
                    colors[index * 4] = thresholdColors[i][0] + t * (thresholdColors[i + 1][0] - thresholdColors[i][0]);
                    colors[index * 4 + 1] = thresholdColors[i][1] + t * (thresholdColors[i + 1][1] - thresholdColors[i][1]);
                    colors[index * 4 + 2] = thresholdColors[i][2] + t * (thresholdColors[i + 1][2] - thresholdColors[i][2]);
                    colors[index * 4 + 3] = 1.0f; // Alpha始终为1
                }
            }
        }

        // 准备缓冲区
        ByteBuffer bb = ByteBuffer.allocateDirect(vertices.length * 4);
        bb.order(ByteOrder.nativeOrder());
        mVertexBuffer = bb.asFloatBuffer();
        mVertexBuffer.put(vertices);
        mVertexBuffer.position(0);

        ByteBuffer cb = ByteBuffer.allocateDirect(colors.length * 4);
        cb.order(ByteOrder.nativeOrder());
        mColorBuffer = cb.asFloatBuffer();
        mColorBuffer.put(colors);
        mColorBuffer.position(0);

        // 绘制代码保持不变...
        GLES20.glUseProgram(mProgram);

        int positionHandle = GLES20.glGetAttribLocation(mProgram, "vPosition");
        int colorHandle = GLES20.glGetAttribLocation(mProgram, "vColor");
        int mvpMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix");
        int pointSizeHandle = GLES20.glGetUniformLocation(mProgram, "uPointSize");

        GLES20.glUniformMatrix4fv(mvpMatrixHandle, 1, false, mMVPMatrix, 0);
        GLES20.glUniform1f(pointSizeHandle, mPointSize);

        GLES20.glEnableVertexAttribArray(positionHandle);
        GLES20.glEnableVertexAttribArray(colorHandle);

        GLES20.glVertexAttribPointer(positionHandle, 3, GLES20.GL_FLOAT, false, 0, mVertexBuffer);
        GLES20.glVertexAttribPointer(colorHandle, 4, GLES20.GL_FLOAT, false, 0, mColorBuffer);

        GLES20.glDrawArrays(GLES20.GL_POINTS, 0, WIDTH * HEIGHT);

        GLES20.glDisableVertexAttribArray(positionHandle);
        GLES20.glDisableVertexAttribArray(colorHandle);
    }

    private void drawPressureMatrix1() {
        float[] vertices = new float[WIDTH * HEIGHT * 3];
        float[] colors = new float[WIDTH * HEIGHT * 4];

        // 计算3D模式下实际显示的宽度（用于统一缩放）
        float visible3DWidth = 2 * CAMERA_Z * (float) Math.tan(Math.toRadians(FOV_3D / 2));
        float xScale = visible3DWidth / WIDTH;
        float yScale = xScale / CONTENT_ASPECT;

        for (int x = 0; x < WIDTH; x++) {
            for (int y = 0; y < HEIGHT; y++) {
                int index = y * WIDTH + x;
                float pressure = mPressureData[index];

                // 基础坐标计算（应用补偿缩放）
                float baseX = (x - WIDTH / 2) * xScale / mBaseScale;
                float baseY = (y - HEIGHT / 2) * yScale / mBaseScale;

                // 3D效果坐标计算
                vertices[index * 3] = baseX;
                vertices[index * 3 + 1] = baseY * (float) Math.cos(Math.toRadians(MAX_TILT_ANGLE * m3DEffectStrength));
                vertices[index * 3 + 2] = (pressure - 0.1f) * MAX_HEIGHT_SCALE * m3DEffectStrength;

                // 颜色计算（基于0.1-1.0范围）
                float normalizedPressure = (pressure - 0.1f) / 0.9f;
                if (normalizedPressure < 0.1f) {
                    colors[index * 4] = 0.0f;
                    colors[index * 4 + 1] = 0.0f;
                    colors[index * 4 + 2] = 0.3f;
                    colors[index * 4 + 3] = 1.0f;
                } else if (normalizedPressure < 0.3f) {
                    float t = (normalizedPressure - 0.1f) / 0.2f;
                    colors[index * 4] = 0.0f;
                    colors[index * 4 + 1] = 0.0f;
                    colors[index * 4 + 2] = 0.3f + t * 0.7f;
                    colors[index * 4 + 3] = 1.0f;
                } else if (normalizedPressure < 0.7f) {
                    float t = (normalizedPressure - 0.3f) / 0.4f;
                    colors[index * 4] = 0.0f;
                    colors[index * 4 + 1] = t;
                    colors[index * 4 + 2] = 1.0f - t * 0.5f;
                    colors[index * 4 + 3] = 1.0f;
                } else {
                    float t = (normalizedPressure - 0.7f) / 0.3f;
                    colors[index * 4] = t;
                    colors[index * 4 + 1] = 1.0f;
                    colors[index * 4 + 2] = 0.5f - t * 0.5f;
                    colors[index * 4 + 3] = 1.0f;
                }
            }
        }

        // 准备缓冲区
        ByteBuffer bb = ByteBuffer.allocateDirect(vertices.length * 4);
        bb.order(ByteOrder.nativeOrder());
        mVertexBuffer = bb.asFloatBuffer();
        mVertexBuffer.put(vertices);
        mVertexBuffer.position(0);

        ByteBuffer cb = ByteBuffer.allocateDirect(colors.length * 4);
        cb.order(ByteOrder.nativeOrder());
        mColorBuffer = cb.asFloatBuffer();
        mColorBuffer.put(colors);
        mColorBuffer.position(0);

        // 绘制
        GLES20.glUseProgram(mProgram);

        int positionHandle = GLES20.glGetAttribLocation(mProgram, "vPosition");
        int colorHandle = GLES20.glGetAttribLocation(mProgram, "vColor");
        int mvpMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix");
        int pointSizeHandle = GLES20.glGetUniformLocation(mProgram, "uPointSize");

        GLES20.glUniformMatrix4fv(mvpMatrixHandle, 1, false, mMVPMatrix, 0);
        GLES20.glUniform1f(pointSizeHandle, mPointSize);

        GLES20.glEnableVertexAttribArray(positionHandle);
        GLES20.glEnableVertexAttribArray(colorHandle);

        GLES20.glVertexAttribPointer(positionHandle, 3, GLES20.GL_FLOAT, false, 0, mVertexBuffer);
        GLES20.glVertexAttribPointer(colorHandle, 4, GLES20.GL_FLOAT, false, 0, mColorBuffer);

        GLES20.glDrawArrays(GLES20.GL_POINTS, 0, WIDTH * HEIGHT);

        GLES20.glDisableVertexAttribArray(positionHandle);
        GLES20.glDisableVertexAttribArray(colorHandle);
    }

    /**
     * 设置3D效果强度
     *
     * @param strength 0.1-1.0之间的值，0.1为轻微3D，1为完整3D效果
     */
    public void set3DEffectStrength(float strength) {
        strength = Math.max(0.1f, Math.min(1.0f, strength)); // 限制在0.1-1.0范围内
        if (Math.abs(mTarget3DEffectStrength - strength) > 0.01f) {
            mTarget3DEffectStrength = strength;
            mTransitionProgress = 0.0f;
        }
    }
}